import Nedb from "nedb";
// var Nedb = require("nedb");
// import * as Nedb from "./nedb.js";
class DB {
  db = null;
  CODE_ERROR = -1; //失败状态码
  CODE_SUCCESS = 200; //成功状态码
  constructor(filename, Indexs) {
    let db = new Nedb({
      filename: filename,
      autoload: true
    });
    db.persistence.setAutocompactionInterval(5000); //数据合并压缩
    for (const i in Indexs) {
      Indexs[i] && Indexs[i].fieldName && db.ensureIndex(Indexs[i]);
    }
    this.db = db;
  }
  exec(action) {
    if (!this.db) {
      return Promise.resolve({
        code: 1,
        message: "没有数据库实例"
      });
    }
    if (!action) {
      return Promise.resolve({
        code: 1,
        message: "没有执行函数(action)"
      });
    }
    return new Promise((resolve, reject) => {
      action(this.db, resolve, reject);
    });
  }

  //插入数据
  insert(params) {
    params && params.id && (params._id = params._id || params.id); //TODO 需要删除
    return this.exec((db, resolve, reject) => {
      var callback = (error, docs) => {
        console.log("[insert] [error]", error, "[docs]", docs);
        let message = "数据保存成功";
        if (error) {
          message = params ? "数据保存失败" : "数据不能为空";
        }
        if (error && error.errorType == "uniqueViolated") {
          message = `${error.key || "名称"}已存在`;
        }
        docs && (docs.id = docs._id); //TODO 需要删除
        let result = {
          code: error ? this.CODE_ERROR : this.CODE_SUCCESS,
          message: message,
          data: docs,
          error
        };
        resolve(result);
      };
      db.insert(params, callback); //添加
    });
  }

  //全量更新单条数据
  update(params, repalce_id) {
    params && params.id && (params._id = params._id || params.id); //TODO 需要删除
    return this.exec((db, resolve, reject) => {
      var callback = (error, docs) => {
        console.log("[update result] [error]", error, "[docs]", docs);
        repalce_id && docs && (docs[repalce_id] = docs._id);
        params && (params.id = params._id); //TODO 需要删除
        let result = {
          code: error ? this.CODE_ERROR : this.CODE_SUCCESS,
          message: error ? "数据保存失败" : "数据保存成功",
          data: params,
          error
        };
        if (docs == 0) {
          result.code = 1;
          result.message = "数据更新失败(数据不存在或已删除)";
        }
        resolve(result);
      };
      console.log("[update] ", params);
      params && params._id
        ? db.update({ _id: params._id }, params, callback) //全量更新单条数据
        : callback("没有主键(_id或id)");
    });
  }

  //列表查询
  findOne(params) {
    params = { _id: params._id || params.id }; //TODO 需要删除
    return this.exec((db, resolve, reject) => {
      var callback = (error, docs) => {
        console.log("[findOne] [error]", error, "[docs]", docs);
        let message = "数据查询成功";
        if (error) {
          message = params && params._id ? "数据查询失败" : "查询id不能为空";
        }
        if (error && error.errorType == "uniqueViolated") {
          message = `${error.key || "名称"}已存在`;
        }
        if (!error && !docs) {
          error = message = "没有查询到相关数据";
        }
        docs && (docs.id = docs._id); //TODO 需要删除
        let result = {
          code: error ? this.CODE_ERROR : this.CODE_SUCCESS,
          message: message,
          data: docs,
          error
        };
        resolve(result);
      };
      db.findOne(params, callback);
    });
  }

  //列表查询
  find({ filter, skip = 0, limit = 100, sort }) {
    let count = this.exec((db, resolve, reject) => {
      db.count({ ...filter })
        .sort({ ...sort }) //{ time: 0 }
        .exec(function (error, count) {
          resolve(count);
        });
    });
    let data = this.exec((db, resolve, reject) => {
      db.find({ ...filter })
        .sort({ ...sort }) //{ time: 0 }
        .skip(skip) //跳过
        .limit(limit) //限制条数
        .exec(function (error, docs) {
          console.log("[find]", error, docs);
          (docs || []).map((item) => (item.id = item._id));
          resolve(docs);
        });
    });
    return Promise.all([count, data])
      .then(([count, docs]) => {
        console.log(count, docs);
        let result = {
          code: !count || !docs ? this.CODE_ERROR : this.CODE_SUCCESS,
          message: !count || !docs ? "查询失败" : "查询成功",
          data: {
            total: count,
            records: docs,
            filter,
            skip,
            limit,
            sort
          }
        };
        return result;
      })
      .catch((error) => {
        console.error(error);
        return {
          code: 1,
          message: "查询失败",
          error
        };
      });
  }

  //删除单条数据
  remove(params) {
    params = { _id: params._id || params.id }; //TODO 需要删除
    return this.exec((db, resolve, reject) => {
      var callback = (error, docs) => {
        console.log("[remove result] [error]", error, "[docs]", docs);
        let result = {
          code: error ? this.CODE_ERROR : this.CODE_SUCCESS,
          message: error ? "数据删除失败" : "数据删除成功",
          data: params,
          error
        };
        if (docs == 0) {
          result.code = 0;
          result.message = "数据删除失败(数据不存在或已删除)";
        }
        resolve(result);
      };
      params._id
        ? db.remove({ _id: params._id }, {}, callback) //全量更新单条数据
        : callback("没有主键 (_id)");
    });
  }
}
export default DB;

if (typeof window == "object") {
  var app = new DB("./nedb/db/app.db");
  window.nedb = { app };
}

// var app = new DB("./nedb/db/app.db", [
//   { fieldName: "applicationName", unique: true },
// ]);
// app.db
//   .find({})
//   .sort({
//     update_ime: 1,
//   })
//   .exec(function (error, doc) {
//     let d = (doc || [])[0] || {};
//     console.log("00000", d.applicationName, d.updateTime);
//   });
